source('dbLib.R')

get.outlier.mask <- function (x, z.factor) {
	errors <- abs(x - mean(x))
	mask <- errors > sd(x) * z.factor
}

normalize <- function (x) {
	(x - mean(x)) / sd(x)
}

diag.panel <- function(dataset) {
	notes <- dataset$NOTE
	pressures <- dataset$PRESSURE
	durations <- dataset$DURATION
	
	quartz(width=5.5,height=10)
	par(mfrow=c(3,2),cex=1.0)
	
	matplot(notes,type=c('s'),col='red')
	matplot(pressures,type=c('l'),col='green')
	abline(h=mean(pressures))
	abline(h=median(pressures),col='red',lty='dashed')
	
	matplot(durations,type=c('l'),col='blue')
	abline(h=mean(durations))
	abline(h=median(pressures),col='red',lty='dashed')
	
	boxplot(notes,type=c('s'),col='red')
	boxplot(pressures,type=c('l'),col='green')
	boxplot(durations,type=c('l'),col='blue')
}

plot.distro <- function(dataset) {
	pressures <- dataset$PRESSURE
	durations<- dataset$DURATION
	quartz(width=5.5,height=10)
	par(mfrow=c(3,2),cex=1.0)
	hist(pressures)
	hist(durations)
	plot(pressures,durations)
	qqplot(pressures,durations)
	qqline(pressures,durations)
	plot(ecdf(pressures))
	plot(ecdf(durations))
}

# remove samples where pressure or duration are outside 
removeOutliers <- function(dataset, Z.FACTOR) {
	pressures <- dataset$PRESSURE
	durations <- dataset$DURATION
	notes <- dataset$NOTE
	pressure.mask <- !get.outlier.mask(pressures,Z.FACTOR)
	duration.mask <- !get.outlier.mask(durations,Z.FACTOR)
	data.mask <- (as.integer(pressure.mask) * as.integer(duration.mask)) == 1
	clean.dataset <- list(
			NOTE = notes[data.mask],
			PRESSURE = pressures[data.mask],
			DURATION =  durations[data.mask]
			)
	clean.dataset
}

scale.time <- function(time) {
	ceiling(time/100) + 1
}

convert.time.domain <- function(raw) {
	maxtime <- max(scale.time(raw$TIME))
	rake <- rep(0,times=128)
	output <- matrix(0,nrow=maxtime,ncol=128)
	last.slot <- 1
	for (i in 1:(nrow(raw)-1)) {
		event <- raw[i,]
		if (event$STATUS == 144) {
			rake[event$NOTE] <- event$PRESSURE
			this.slot <- scale.time(event$TIME)
			output[last.slot:this.slot,] <- rake
			last.slot <- this.slot
		} else {
			rake[raw$NOTE] <- 0
		}
	}
	output
}

record <- data.frame(matrix(nrow=0,ncol=4))

# Run interactive monitor (TCP)
# TCP Server must be running on MIDI source
run <- function(host = "localhost") {
	a <- make.socket(host, port=8100, server=T)
	on.exit(close.socket(a))
	NOTE.DOWN <- 144
	NOTE.UP <-128
	varnames <- c('time','note','status','pressure')
	note <- 0
	last.time <- 0
	delay <- NULL
	pressures <- NULL
	notes <- NULL
	times <- NULL
	graphics.off()
	par(mfrow=c(2,1))
	print('Listening on port 8100')
	overflow.values <- c()
	
	while (note != 21) {
		m <- read.socket(a)
		print(m)
		v <- c(overflow.values, as.integer(unlist(strsplit(m,"\n|\\s"))))
		message.count <- floor(length(v) / 4)
		overflow.value.count <- length(v) %% 4
		new.values <- matrix(v[seq(0,message.count * 4)],ncol=4,byrow=TRUE)
		colnames(record) <- varnames
		colnames(new.values) <- varnames
		record <- rbind(record,new.values)
		colnames(record) <- varnames
		if (overflow.value.count > 0) {
			overflow.values <- v[seq(message.count * 4 + 1,length(v))]
		}
		print(record)
		plot(record$time,record$note,typ='s',col='green',ylim=c(0,128))
		plot(record$time,record$pressure,typ='s',col='blue',ylim=c(0,128))
	}
}

make.duration.time.series <- function(raw) {
	#*************
	# ------>>>>>> rawi[rawi$NOTE==52 & rawi$STATUS==144,]$TIME - rawi[rawi$NOTE==52 & rawi$STATUS==128,]
	#*************
	series <- list()
	for (note in sort(unique(raw$NOTE))) {
		current.note <- raw[raw$NOTE == note, ]
		down <- current.note[current.note$STATUS==144,]
		up <- current.note[current.note$STATUS==128,]
		keystrokes <- cbind(down[,c('TIME','NOTE','PRESSURE')] , DURATION=(up$TIME - down$TIME))
		series <- rbind(series,keystrokes)
	}
	series[order(series$TIME),]
}


something <- function() {
	graphics.off()
	
	#*** Load source file (MIDI note events)
	raw <- read.table(file="../data/mididata.txt",header=T)
	series <- make.duration.time.series(raw)
	quartz()
	pairs(series)
	quartz()
	quartz(width=5.5,height=10)
	par(mfrow=c(2,1),cex=1.0)
	matplot(cbind(series$DURATION,filter(series$DURATION,rep(1/40,40))),type="l",lty=1,ylab="Duration")
	matplot(cbind(series$PRESSURE,filter(series$PRESSURE,rep(1/40,40))),type="l",lty=1,ylab="Pressure")
	
	#*** Plot distribution
	
	plot.distro(series)
	diag.panel(series)
	series.f1 <- removeOutliers(series,1)
	diag.panel(series.f1)
	title("Clean data")
}
